package com.ys.erp.common.util;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author lwj
 * @date 2024/9/6
 */
public class YsThread {

    private static final ExecutorService VIRTUAL_THREAD_POOL = Executors.newVirtualThreadPerTaskExecutor();

    public static <T> CompletableFuture<T> execute(Supplier<T> supplier) {
        return CompletableFuture.supplyAsync(supplier, VIRTUAL_THREAD_POOL);
    }

    public static void execute(Runnable runnable) {
        VIRTUAL_THREAD_POOL.submit(runnable);
    }

    public static <T, R> CompletableFuture<List<R>> execute(Collection<T> collection, Function<T, R> task) {
        List<CompletableFuture<R>> futures = collection.stream()
                .map(item -> CompletableFuture.supplyAsync(() -> task.apply(item), VIRTUAL_THREAD_POOL))
                .toList();

        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                .thenApply(v -> futures.stream()
                        .map(CompletableFuture::join)
                        .collect(Collectors.toList()));
    }

    public static <T> CompletableFuture<Void> execute(Collection<T> collection, Consumer<T> task) {
        List<CompletableFuture<Void>> futures = collection.stream()
                .map(item -> CompletableFuture.runAsync(() -> task.accept(item), VIRTUAL_THREAD_POOL))
                .toList();

        return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
    }




}
